﻿using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using System;
using Terraria;
using Terraria.GameContent;
using Terraria.ID;
using Terraria.ModLoader;

namespace HardcoreGame.Content.Projectiles.Ranged
{
    public class CurseFlame : ModProjectile
    {
        public override void SetStaticDefaults()
        {
            ProjectileID.Sets.TrailingMode[Type] = 3;
            ProjectileID.Sets.TrailCacheLength[Type] = 60;
            Main.projFrames[Type] = 7;
        }
        public override void SetDefaults()
        {
            Projectile.width = 6;
            Projectile.height = 6;
            Projectile.aiStyle = -1;
            Projectile.friendly = true;
            Projectile.alpha = 255;
            Projectile.penetrate = 4;
            Projectile.extraUpdates = 2;
            Projectile.DamageType = DamageClass.Ranged;
            Projectile.usesLocalNPCImmunity = true;
            Projectile.localNPCHitCooldown = -1;
        }
        public override void OnHitNPC(NPC target, NPC.HitInfo hit, int damageDone)
        {
            hit.Damage = (int)(hit.Damage * 0.85);
            int num4 = Projectile.ai[0] == 1f ? 39 : 39;
            target.AddBuff(num4, 1200);
        }
        public override void OnHitPlayer(Player target, Player.HurtInfo info)
        {
            target.AddBuff(39, 1200, quiet: false);
        }
        public override bool? CanDamage()
        {
            if (Projectile.localAI[0] >= (float)54f)
            {
                return new bool?(false);
            }
            return null;
        }
        public override void AI()
        {
            if (Projectile.wet)
            {
                Projectile.Kill();
            }
            Projectile.localAI[0] += 1f;
            int num = 60;
            int num2 = 12;
            int num3 = num + num2;
            if (Projectile.localAI[0] >= num3)
            {
                Projectile.Kill();
            }
            if (Projectile.localAI[0] >= num)
            {
                Projectile.velocity *= 0.95f;
            }
            bool flag = Projectile.ai[0] == 1f;
            int num4 = 50;
            int num5 = num4;
            if (flag)
            {
                num4 = 0;
                num5 = num;
            }
            if (Projectile.localAI[0] < num5 && Main.rand.NextFloat() < 0.25f)
            {
                short num6 = (short)(flag ? 135 : 75);
                Dust dust = Dust.NewDustDirect(Projectile.Center + Main.rand.NextVector2Circular(60f, 60f) * Utils.Remap(Projectile.localAI[0], 0f, 72f, 0.5f, 1f), 4, 4, num6, Projectile.velocity.X * 0.2f, Projectile.velocity.Y * 0.2f, 100);
                if (Main.rand.NextBool(4))
                {
                    dust.noGravity = true;
                    dust.scale *= 3f;
                    dust.velocity.X *= 2f;
                    dust.velocity.Y *= 2f;
                }
                else
                {
                    dust.scale *= 1.5f;
                }
                dust.scale *= 1.5f;
                dust.velocity *= 1.2f;
                dust.velocity += Projectile.velocity * 1f * Utils.Remap(Projectile.localAI[0], 0f, num * 0.75f, 1f, 0.1f) * Utils.Remap(Projectile.localAI[0], 0f, num * 0.1f, 0.1f, 1f);
                dust.customData = 1;
            }
            if (num4 > 0 && Projectile.localAI[0] >= num4 && Main.rand.NextFloat() < 0.5f)
            {
                Vector2 center = Main.player[Projectile.owner].Center;
                Vector2 vector = (Projectile.Center - center).SafeNormalize(Vector2.Zero).RotatedByRandom(0.19634954631328583) * 7f;
                short num7 = 31;
                Dust dust2 = Dust.NewDustDirect(Projectile.Center + Main.rand.NextVector2Circular(50f, 50f) - vector * 2f, 4, 4, num7, 0f, 0f, 150, new Color(80, 80, 80));
                dust2.noGravity = true;
                dust2.velocity = vector;
                dust2.scale *= 1.1f + Main.rand.NextFloat() * 0.2f;
                dust2.customData = -0.3f - 0.15f * Main.rand.NextFloat();
            }

        }
        public override bool OnTileCollide(Vector2 oldVelocity)
        {
            Projectile.velocity = oldVelocity * 0.95f;
            Projectile.position -= Projectile.velocity;
            return false;
        }
        public override bool? Colliding(Rectangle projHitbox, Rectangle targetHitbox)
        {
            if (!projHitbox.Intersects(targetHitbox))
            {
                return new bool?(false);
            }
            return new bool?(Collision.CanHit(Projectile.Center, 0, 0, targetHitbox.Center.ToVector2(), 0, 0));
        }
        public override void ModifyDamageHitbox(ref Rectangle hitbox)
        {
            int num = (int)Utils.Remap(Projectile.localAI[0], 0f, 72f, 10f, 40f);
            hitbox.Inflate(num, num);
        }
        public override bool PreDraw(ref Color lightColor)
        {
            DrawProj_Flamethrower(Projectile);
            return false;
        }
        private static void DrawProj_Flamethrower(Projectile proj)
        {
            bool flag = proj.ai[0] == 1f;
            float num = 60f;
            float num2 = 12f;
            float fromMax = num + num2;
            Texture2D value = TextureAssets.Projectile[proj.type].Value;
            Color transparent = Color.Transparent;
            Color color = new(100, 255, 5, 200);
            Color color2 = new(200, 255, 10, 70);
            Color color3 = Color.Lerp(new Color(100, 255, 5, 100), color2, 0.25f);
            Color color4 = new(80, 80, 80, 100);
            float num3 = 0.35f;
            float num4 = 0.7f;
            float num5 = 0.85f;
            float num6 = proj.localAI[0] > num - 10f ? 0.175f : 0.2f;
            if (flag)
            {
                color = new Color(100, 255, 5, 200);
                color2 = new Color(200, 255, 10, 70);
                color3 = new Color(100, 255, 5, 100);
                color4 = new Color(80, 80, 80, 100);
            }
            int verticalFrames = 7;
            float num9 = Utils.Remap(proj.localAI[0], num, fromMax, 1f, 0f);
            float num10 = Math.Min(proj.localAI[0], 20f);
            float num11 = Utils.Remap(proj.localAI[0], 0f, fromMax, 0f, 1f);
            float num12 = Utils.Remap(num11, 0.2f, 0.5f, 0.25f, 1f);
            Rectangle rectangle = !flag ? value.Frame(1, verticalFrames, 0, 3) : value.Frame(1, verticalFrames, 0, (int)Utils.Remap(num11, 0.5f, 1f, 3f, 5f));
            if (!(num11 < 1f))
            {
                return;
            }
            for (int i = 0; i < 2; i++)
            {
                for (float num13 = 1f; num13 >= 0f; num13 -= num6)
                {
                    transparent = num11 < 0.1f ? Color.Lerp(Color.Transparent, color, Utils.GetLerpValue(0f, 0.1f, num11, clamped: true)) : num11 < 0.2f ? Color.Lerp(color, color2, Utils.GetLerpValue(0.1f, 0.2f, num11, clamped: true)) : num11 < num3 ? color2 : num11 < num4 ? Color.Lerp(color2, color3, Utils.GetLerpValue(num3, num4, num11, clamped: true)) : num11 < num5 ? Color.Lerp(color3, color4, Utils.GetLerpValue(num4, num5, num11, clamped: true)) : !(num11 < 1f) ? Color.Transparent : Color.Lerp(color4, Color.Transparent, Utils.GetLerpValue(num5, 1f, num11, clamped: true));
                    float num14 = (1f - num13) * Utils.Remap(num11, 0f, 0.2f, 0f, 1f);
                    Vector2 vector = proj.Center - Main.screenPosition + proj.velocity * (0f - num10) * num13;
                    Color color5 = transparent * num14;
                    Color color6 = color5;
                    if (!flag)
                    {
                        color6.G /= 2;
                        color6.B /= 2;
                        color6.A = (byte)Math.Min(color5.A + 80f * num14, 255f);
                        Utils.Remap(proj.localAI[0], 20f, fromMax, 0f, 1f);
                    }
                    float num15 = 1f / num6 * (num13 + 1f);
                    float num16 = proj.rotation + num13 * ((float)Math.PI / 2f) + Main.GlobalTimeWrappedHourly * num15 * 2f;
                    float num17 = proj.rotation - num13 * ((float)Math.PI / 2f) - Main.GlobalTimeWrappedHourly * num15 * 2f;
                    switch (i)
                    {
                        case 0:
                            Main.EntitySpriteDraw(value, vector + proj.velocity * (0f - num10) * num6 * 0.5f, rectangle, color6 * num9 * 0.25f, num16 + (float)Math.PI / 4f, rectangle.Size() / 2f, num12, SpriteEffects.None);
                            Main.EntitySpriteDraw(value, vector, rectangle, color6 * num9, num17, rectangle.Size() / 2f, num12, SpriteEffects.None);
                            break;
                        case 1:
                            if (!flag)
                            {
                                Main.EntitySpriteDraw(value, vector + proj.velocity * (0f - num10) * num6 * 0.2f, rectangle, color5 * num9 * 0.25f, num16 + (float)Math.PI / 2f, rectangle.Size() / 2f, num12 * 0.75f, SpriteEffects.None);
                                Main.EntitySpriteDraw(value, vector, rectangle, color5 * num9, num17 + (float)Math.PI / 2f, rectangle.Size() / 2f, num12 * 0.75f, SpriteEffects.None);
                            }
                            break;
                    }
                }
            }
        }
    }
}
